package com.hns.can.base.web;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.hns.can.base.entity.SysAnnouncementEntity;
import com.hns.can.base.entity.SysAuthrityFieldValueEntity;
import com.hns.can.base.entity.SysOperateLogEntity;
import com.hns.can.base.entity.SysRoleEntity;
import com.hns.can.base.entity.SysUserEntity;
import com.hns.can.base.enumrate.FuncLevel;
import com.hns.can.base.service.LoginService;
import com.hns.can.base.service.SysAuthorityButtonService;
import com.hns.can.base.service.SysAuthorityFuncService;
import com.hns.can.base.service.SysFuncService;
import com.hns.can.base.service.SysRoleService;
import com.hns.can.base.vo.MenuVo;
import com.hns.can.common.constants.SysCache;
import com.hns.can.common.web.BaseController;
import com.hns.frame.enumrate.MsgType;
import com.hns.frame.exception.BusinessException;
import com.hns.tool.pub.FTPUtils;
import com.hns.tool.pub.PubUtil;
import com.hns.tool.pub.UtilConfig;
import com.hns.tool.pub.UtilString;

/**
 * 登录功能
 * @author:Fisher
 * @email:zhuangcaijin@126.com
 * @version Revision 2.0.0
 */
@Controller
@SessionAttributes({"SES_CURRENTUSER","SES_ORGANLIST", "SES_ROLELIST", "SES_AUTHORITY", "SES_THIRDMENU", "SES_ALLAUTHORITY"})
@RequestMapping("/logon")
public class LogonController extends BaseController {
    
    @Autowired
    private SysRoleService sysRoleService;
    
    @Autowired
    private SysFuncService sysFuncService;
    
    @Autowired
    private LoginService loginService;
    
    @Autowired
    private SysAuthorityButtonService sysAuthorityButtonService;
    
    @Autowired
    private SysAuthorityFuncService sysAuthorityFuncService;
    
    /**
     * @param request
     * @param map
     * @return
     * @author:Fisher
     * @email:zhuangcaijin@126.com
     * @创建日期:2014-3-31
     * @功能说明：登录入口
     */
    @RequestMapping("/enter")
    public ModelAndView enter(HttpServletRequest request, Map<String, Object> map) throws Exception {
    	/*VerifyLicense vLicense = new VerifyLicense(request.getSession().getServletContext() .getRealPath("/WEB-INF/classes/"));
    	try{
    	    if(!vLicense.verify()){
                return new ModelAndView("common/licenseExpired");
            }
    	}catch(Exception e){
    	    return new ModelAndView("common/licenseExpired");
    	}*/
		
    	BigDecimal beginTime = new BigDecimal(System.currentTimeMillis());
        if (this.getAppCurrentUser() == null) {//由于获取当前用户为null时加了抛出自定义异常，这里获取当前用户方式使用app部分的，待改动
            return new ModelAndView(new RedirectView("logon/commonQuit.htm"));
        }
        
        // 获取当前用户信息
        final SysUserEntity currentUser = this.getCurrentUser().getUser();
        // 将用户对应的角色列表放入session
        map.put("SES_CURRENTUSER", currentUser);
        // 获取用户对应的角色
        List<SysRoleEntity> sysRoleList = sysRoleService.getSysRoleListByUserId(currentUser.getId());
        // 获取角色对应的组织机构权限
        List<String> sysAuthorityResourceEntityList = loginService.getAuthorityResource(sysRoleList);
        map.put("SES_ORGANLIST", sysAuthorityResourceEntityList);
        
        //初始化资源类别权限
        sysAuthorityFuncService.getAuthFieldValue(currentUser.getId());
        List<SysAuthrityFieldValueEntity> authFieldValueList = sysAuthorityFuncService.getAuthFieldValue(currentUser.getId());
        SysCache.setAuthrityFieldValue(currentUser.getId(), authFieldValueList);
        
        //设置本地socket地址
        String localSocketServer = UtilConfig.getString("local_socket_server");
        String innerLocalSocketServer = UtilConfig.getString("inner_local_socket_server");
        if(PubUtil.isEmpty(localSocketServer) || PubUtil.isEmpty(innerLocalSocketServer)){
            throw new BusinessException(MsgType.ERROR.getFlag(), "未设置本地socket地址");
        }
        map.put("localSocketServer", localSocketServer);
        map.put("innerLocalSocketServer", innerLocalSocketServer);
        
        String localSocketServer2 = UtilConfig.getString("local_socket_server2");
        String innerLocalSocketServer2 = UtilConfig.getString("inner_local_socket_server2");
        if(PubUtil.isEmpty(localSocketServer2) || PubUtil.isEmpty(innerLocalSocketServer2)){
            throw new BusinessException(MsgType.ERROR.getFlag(), "未设置本地socket2地址");
        }
        map.put("localSocketServer2", localSocketServer2);
        map.put("innerLocalSocketServer2", innerLocalSocketServer2);
        
        //思创外网，内网ip
        map.put("outerIp", UtilConfig.getString("outer_ip"));
        map.put("innerIp", UtilConfig.getString("inner_ip"));
        
        
        //监控webservice地址
        String qzjSocketServer = UtilConfig.getString("qzj_socket_server");
        String innerQzjSocketServer = UtilConfig.getString("inner_qzj_socket_server");
        
        if(PubUtil.isEmpty(qzjSocketServer) || PubUtil.isEmpty(innerQzjSocketServer)){
            throw new BusinessException(MsgType.ERROR.getFlag(), "未设置前置机socket地址");
        }
        map.put("qzjSocketServer", qzjSocketServer);
        map.put("innerQzjSocketServer", innerQzjSocketServer);
        
        
        
        String qzjWssocketServer = UtilConfig.getString("qzj_wssocket_server");
        String innerQzjWssocketServer = UtilConfig.getString("inner_qzj_wssocket_server");
        
        if(PubUtil.isEmpty(qzjWssocketServer) || PubUtil.isEmpty(innerQzjWssocketServer)){
            throw new BusinessException(MsgType.ERROR.getFlag(), "未设置前置机Wssocket地址");
        }
        map.put("qzjWssocketServer", qzjWssocketServer);
        map.put("innerQzjWssocketServer", innerQzjWssocketServer);
        
        
        BigDecimal endTime = new BigDecimal(System.currentTimeMillis());
        
        //写入日志
        String ip = PubUtil.getRemortIP((HttpServletRequest)request);
        SysOperateLogEntity entity = new SysOperateLogEntity();
        entity.setLogId(UtilString.getUUID());
        entity.setCorpId(currentUser.getCorpId());
        entity.setOprId(currentUser.getId());
        entity.setMnpltTime(new Date());
        entity.setMnpltUrl("/logon/enter.htm");
        entity.setMnpltDura(endTime.subtract(beginTime));
        entity.setIpAdr(ip);
//        ClientMacAddr mac = new ClientMacAddr(ip);
//        entity.setMacAdr(mac.GetRemoteMacAddr());
        //entity.setMnpltFunc(menuVo.getId());
        entity.setMnpltType("OLOG0001");
        entity.setSystemId("CLOUD_CAN_V2.0");
        loginService.saveSysOperateLog(entity);
        
        return new ModelAndView("common/main", map);
    }
    
    /**
     * 获取当前用户信息
     * @return 当前用户
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @RequestMapping("/getCurrentUser")
    @ResponseBody
    public Object getUser(){
        return this.getReturnResult(this.getCurrentUser().getUser());
    }
    
    /**
     * 获取用户对应的菜单
     * @return
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
    @RequestMapping("/getMenuListByUser")
    @ResponseBody
    public Object getFuncListByUser(Map<String, Object> map) throws Exception {
    	SysUserEntity user = this.getCurrentUser().getUser();
    	List<SysRoleEntity> roleList = sysRoleService.getSysRoleListByUserId(user.getId());
    	List<MenuVo> functionThreeLevelList = getFunctionThreeLevelList(roleList, map);
    	return this.getReturnResult(functionThreeLevelList);
    }
    
    /**
     * @param sysRoleList
     * @param map
     * @return
     * @author:Fisher
     * @email:zhuangcaijin@126.com
     * @创建日期:2014-6-11
     * @功能说明：获取菜单列表，并将三级菜单放入session
     */
    private List<MenuVo> getFunctionThreeLevelList(List<SysRoleEntity> sysRoleList, Map<String, Object> map) throws Exception {
        // 取出用户对应的所有(角色的id)
        List<String> roleIdList = new ArrayList<String>();
        for (SysRoleEntity entity : sysRoleList) {
            roleIdList.add(entity.getId());
        }
        // 获取用户角色对应的(所有功能权限)
        List<MenuVo> sysFuncList = sysFuncService.getSysFuncListForLog(roleIdList);
        map.put("SES_ALLAUTHORITY", sysFuncList);// 包括功能权限和按钮权限
        if (PubUtil.isEmpty(sysFuncList)) {
            sysFuncList = new ArrayList<MenuVo>();
            return sysFuncList;
        }
        // 一级菜单列表初始化
        List<MenuVo> firstFuncLevelList = new ArrayList<MenuVo>();
        // 一级菜单对应的二级菜单初始化
        Map<String, List<MenuVo>> secondFuncLevelMap = new LinkedHashMap<String, List<MenuVo>>();
        // 二级菜单对应的三级菜单初始化
        Map<String, List<MenuVo>> thirdFuncLevelMap = new LinkedHashMap<String, List<MenuVo>>();
        //三级菜单对应的四级菜单初始化
        Map<String, List<MenuVo>> forthFuncLevelMap = new LinkedHashMap<String, List<MenuVo>>();
        //四级菜单对应的五级菜单初始化
        Map<String, List<MenuVo>> fifthFuncLevelMap = new LinkedHashMap<String, List<MenuVo>>();
        // 设置一级菜单列表、一级菜单对应的二级菜单、二级菜单对应的三级菜单
        for (MenuVo entity : sysFuncList) {
            int level = entity.getScale().intValue();
            if (level == FuncLevel.FIRST.getFlag()) {
            	entity.setScale(null);
            	entity.setParentId(null);
            	entity.setPosition(null);
                firstFuncLevelList.add(entity);
            } else if (level == FuncLevel.SECOND.getFlag()) {
                secondFuncLevelMap = returnResMap(entity, secondFuncLevelMap);
            } else if (level == FuncLevel.THIRD.getFlag()) {
                thirdFuncLevelMap = returnResMap(entity, thirdFuncLevelMap);
            } else if(level == FuncLevel.FORTH.getFlag()){
            	forthFuncLevelMap = returnResMap(entity, forthFuncLevelMap);
            } else if(level == FuncLevel.FIFTH.getFlag()){
            	fifthFuncLevelMap = returnResMap(entity, fifthFuncLevelMap);
            }
            
        }
//        map.put("SES_THIRDMENU", thirdFuncLevelMap);
        
        // 功能菜单的List
        List<MenuVo> funcList = new ArrayList<MenuVo>();
        for (MenuVo first : firstFuncLevelList) {
            // 二级菜单的List
            List<MenuVo> secondList = secondFuncLevelMap.get(first.getId());
            if (PubUtil.isNotEmpty(secondList)) {
            	for (MenuVo second : secondList) {
            		//三级菜单的List
            		List<MenuVo> thirdList = thirdFuncLevelMap.get(second.getId());
            		if (PubUtil.isNotEmpty(thirdList)) {
            			for(MenuVo third : thirdList){
            				//四级菜单List
            				List<MenuVo> forthList = forthFuncLevelMap.get(third.getId());
            				if(PubUtil.isNotEmpty(forthList)){
            					for(MenuVo forth : forthList){
            						//五级菜单List
            						List<MenuVo> fifthList = fifthFuncLevelMap.get(forth.getId());
            						if(PubUtil.isNotEmpty(fifthList)){
            							forth.setChild(fifthList);
            						}
            					}
            					third.setChild(forthList);
            				}
            			}
            			second.setChild(thirdList);
            		}
            	}
                first.setChild(secondList);
            }
            funcList.add(first);
        }
        return funcList;
    }
    
    /**
     * @param entity
     * @param returnMap
     * @return
     * @author:Fisher
     * @email:zhuangcaijin@126.com
     * @创建日期:2014-5-22
     * @功能说明：各级菜单map组装
     */
    private Map<String, List<MenuVo>> returnResMap(MenuVo entity, Map<String, List<MenuVo>> returnMap) throws Exception {
    	String parentId = entity.getParentId();
    	entity.setScale(null);
    	entity.setParentId(null);
    	entity.setPosition(null);
        if (returnMap.containsKey(parentId)) {
            List<MenuVo> list = returnMap.get(parentId);
            list.add(entity);
        } else {
            List<MenuVo> list = new ArrayList<MenuVo>(); // 重新声明一个数组list
            list.add(entity);
            returnMap.put(parentId, list);
        }
        return returnMap;
    }
    
    /**
     * session过期
     * @param request
     * @param response
     * @return
     * @throws Exception
     * @author:Fisher
     * @email:zhuangcaijin@126.com
     */
    @RequestMapping("/commonSessionExpired")
    public ModelAndView commonSessionExpired(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return new ModelAndView("common/expired");
    }
    
    /**
     * 退出
     * @param status 
     * @return 跳转逻辑名
     * @throws Exception
     * @author:zhangyu
     * @email:zhangyu2222z@sina.cn
     */
	@RequestMapping("/commonQuit")
	public ModelAndView commonQuit(HttpServletRequest request,SessionStatus status) throws Exception{
	    /*VerifyLicense vLicense = new VerifyLicense(request.getSession().getServletContext().getRealPath("/WEB-INF/classes/"));
        if(!vLicense.verify()){
            return new ModelAndView("common/licenseExpired");
        }*/
	    if(PubUtil.isNotEmpty(this.getAppCurrentUser())){
	        BigDecimal beginTime = new BigDecimal(System.currentTimeMillis());
	    	SysUserEntity currentUser = this.getCurrentUser().getUser();
	    	//清除用户资源权限缓存
	    	SysCache.clearAuthrityFieldValue(currentUser.getId());
	        BigDecimal endTime = new BigDecimal(System.currentTimeMillis());
	        String ip = PubUtil.getRemortIP(request);
	        SysOperateLogEntity entity = new SysOperateLogEntity();
	        entity.setLogId(UtilString.getUUID());
	        entity.setCorpId(currentUser.getCorpId());
	        entity.setOprId(currentUser.getId());
	        entity.setMnpltTime(new Date());
	        entity.setMnpltUrl("/logon/commonQuit.htm");
	        entity.setMnpltDura(endTime.subtract(beginTime));
	        entity.setIpAdr(ip);
//        ClientMacAddr mac = new ClientMacAddr(ip);
//        entity.setMacAdr(mac.GetRemoteMacAddr());
	        //entity.setMnpltFunc(menuVo.getId());
	        entity.setMnpltType("OLOG0002");
	        entity.setSystemId("CLOUD_CAN_V2.0");
	        loginService.saveSysOperateLog(entity);
	    }
	    
	    status.setComplete();
	    return new ModelAndView(new RedirectView("/bus_logout",true,false,false));
	}
	
	/**
	 * 加载本月系统公告
	 * @return
	 */
	@RequestMapping("getNoticeList")
	@ResponseBody
	public Object getNoticeList(){
		List<SysAnnouncementEntity> list = loginService.getNoticeList(this.getCurrentUser().getUser().getCorpId());
		return this.getReturnResult(list);
	}
	
	
	
	/*@RequestMapping("/commonAppDownloadIndex")
    public ModelAndView commonAppDownloadIndex(HttpServletRequest request, 
    		HttpServletResponse response, Map<String, String> map) throws Exception {
		map.put("outerIp", UtilConfig.getString("outer_ip"));
        map.put("innerIp", UtilConfig.getString("inner_ip"));
        map.put("outerLoginEwm", UtilConfig.getString("outer_login_ewm"));
        map.put("innerLoginEwm", UtilConfig.getString("inner_login_ewm"));
		
        return new ModelAndView("/common/appDownloadIndex");
    }
	
	
	
	@RequestMapping("/commonAppDownloadPage")
    public ModelAndView commonAppDownloadPage(HttpServletRequest request, 
    		HttpServletResponse response, Map<String, String> map) throws Exception {
		map.put("outerIp", UtilConfig.getString("outer_ip"));
        map.put("innerIp", UtilConfig.getString("inner_ip"));
        map.put("outerLoginEwm", UtilConfig.getString("outer_login_ewm"));
        map.put("innerLoginEwm", UtilConfig.getString("inner_login_ewm"));
		
        return new ModelAndView("/common/appDownloadPage");
    }*/
	
	/**
	 * 获取配置
	 * @return
	 * @author:zhangy
	 * @email:zhangyu2222z@sina.cn
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@RequestMapping("commonUrlInfo")
	@ResponseBody
	public Object commonUrlInfo(){
		HashMap map = new HashMap();
		map.put("outerIp", UtilConfig.getString("outer_ip"));
        map.put("innerIp", UtilConfig.getString("inner_ip"));
        map.put("outerLoginEwm", UtilConfig.getString("outer_login_ewm"));
        map.put("innerLoginEwm", UtilConfig.getString("inner_login_ewm"));
        
        map.put("outerAndUrl", UtilConfig.getString("outer_and_url"));
        map.put("innerAndUrl", UtilConfig.getString("inner_and_url"));
        map.put("outerAndUrl2", UtilConfig.getString("outer_and_url2"));
        map.put("innerAndUrl2", UtilConfig.getString("inner_and_url2"));
        map.put("outerIosUrl", UtilConfig.getString("outer_ios_url"));
        map.put("innerIosUrl", UtilConfig.getString("inner_ios_url"));
        map.put("outerIosUrl2", UtilConfig.getString("outer_ios_url2"));
        map.put("innerIosUrl2", UtilConfig.getString("inner_ios_url2"));
        
        map.put("outerAppEwm", UtilConfig.getString("outer_app_ewm"));
        map.put("innerAppEwm", UtilConfig.getString("inner_app_ewm"));
        map.put("outerMainEwm", UtilConfig.getString("outer_main_ewm"));
        map.put("innerMainEwm", UtilConfig.getString("inner_main_ewm"));
		
		return this.getReturnResult(map);
	}
    
}
